﻿using System;
using System.Collections.Generic;
using System.Text;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.ConditionalAppearance;
using DevExpress.ExpressApp.Editors;
using DevExpress.ExpressApp;

namespace DomainComponents.XCRM {
    public enum OpportunityStatus {
        None = 0,
        Won = 1,
        Canceled = 2,
        [DisplayName("Out-Sold")]
        OutSold = 3
    }
    public enum OpportunityRating {
        Hot = 0,
        Warm = 1,
        Cold = 2
    }

    public class OpportunityValidationRules {
        public const string ProbabilityIsBeetwen0And100 = "ProbabilityyIsBeetwen0And100";
    }

    [DomainComponent]
    public interface IOpportunityCustomer : ICustomer {
        [BackReferenceProperty("BackRefCustomer")]
        IList<IOpportunity> Opportunities { get; }
    }

    [DomainComponent]
    public interface IOpportunityTarget {
        [VisibleInListView(false)]
        IOpportunity SourceOpportunity { get; set; }
    }

    [DomainComponent]
    public interface IOpportunityInvoice : IInvoice, IOpportunityTarget {
        [System.ComponentModel.Browsable(false)]
        IOpportunity BackRefOpportunity { get; set; }
    }

    [DomainLogic(typeof(IOpportunityInvoice))]
    public class OpportunityInvoiceLogic {
        public static void AfterChange_BackRefOpportunity(IOpportunityInvoice obj) {
            obj.SourceOpportunity = obj.BackRefOpportunity;
        }
        public static void AfterChange_SourceOpportunity(IOpportunityInvoice obj) {
            obj.BackRefOpportunity = obj.SourceOpportunity;
        }
    }

    [DomainComponent]
    [VisibleInReports]
    [XafDisplayName("Opportunity")]
    [ImageName("BO_Opportunity")]
    [Appearance("Disable IOpportunity by StatusReason", TargetItems = "*", Criteria = "Status != 'None'", Enabled = false)]
    [Appearance("Hide Amount, Discount, DiscountPercent by Empty Criteria", TargetItems = "Amount, Discount, DiscountPercent", Criteria = "", Visibility = ViewItemVisibility.Hide)]
    [Appearance("Enable EstimatedRevenue", TargetItems = "EstimatedRevenue", Criteria = "RevenueIsUserProvided", Enabled = true)]
    [Appearance("Disable EstimatedRevenue", TargetItems = "EstimatedRevenue", Criteria = "!RevenueIsUserProvided", Enabled = false)]
    public interface IOpportunity : ISaleBase {
        OpportunityRating Rating { get; set; }

        OpportunityStatus Status { get; set; }

        decimal EstimatedRevenue { get; set; }

        [VisibleInListView(false)]
        decimal ActualRevenue { get; set; }

        [RuleRange(OpportunityValidationRules.ProbabilityIsBeetwen0And100, DefaultContexts.Save, 0, 100)]
        int Probability { get; set; }

        [VisibleInListView(false)]
        DateTime CloseDate { get; set; }

        [VisibleInListView(false)]
        DateTime EstimatedCloseDate { get; set; }
       
        [BackReferenceProperty("BackRefOpportunity")]
        IList<IOpportunityInvoice> Invoices { get; }
        
        [ImmediatePostData]
        [VisibleInListView(false)]
        bool RevenueIsUserProvided { get; set; }

        [Action(PredefinedCategory.RecordEdit, Caption = "Close Opportunity...", AutoCommit = true,
            TargetObjectsCriteria = "Status = 'None'",
            SelectionDependencyType = MethodActionSelectionDependencyType.RequireSingleObject)]
        void Close(CloseOpportunityParameters parameters);
        
        [System.ComponentModel.Browsable(false)]
        IOpportunityCustomer BackRefCustomer { get; set; }//TODO: duplicated with IInvoce, IOpportunity, IOrder, IQuote
    }


    [DomainLogic(typeof(IOpportunity))]
    public class OpportunityLogic {
        public static void AfterChange_RevenueIsUserProvided(IOpportunity opportunity) {
            opportunity.UpdateAmount();
        }
        public static void UpdateAmount(IOpportunity opportunity) {
            opportunity.Amount = opportunity.DetailAmount;

            if(!opportunity.RevenueIsUserProvided) {
                opportunity.EstimatedRevenue = opportunity.Amount;
            }
        }
        public static void AfterChange_BackRefCustomer(IOpportunity saleBase) {
            saleBase.PotentialCustomer = saleBase.BackRefCustomer;
        }
        public static void AfterChange_PotentialCustomer(IOpportunity saleBase) {
            saleBase.BackRefCustomer = (IOpportunityCustomer)saleBase.PotentialCustomer;
        }
    }
}
